package com.hitalkie.teacher.tx;

import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.hitalkie.teacher.activity.LiveActivity;
import com.tencent.TIMCallBack;
import com.tencent.TIMConversationType;
import com.tencent.TIMGroupManager;
import com.tencent.TIMManager;
import com.tencent.TIMValueCallBack;
import com.tencent.av.sdk.AVContext;
import com.tencent.av.sdk.AVRoomMulti;

import java.util.ArrayList;


/**
 * 进出房间Presenter
 */
public class EnterLiveHelper {
    private LiveActivity mStepInOutView;
    private Context mContext;
    private static final String TAG = EnterLiveHelper.class.getSimpleName();
    private static boolean isInChatRoom = false; // 进入im房间后true，退出im房间后false
    private static boolean isInAVRoom = false; // AVRoomMulti.EventListener 的进入回调true，退出回调false
    private LiveHelper mLiveHelper;
    private ArrayList<String> video_ids = new ArrayList<String>();

    private static final int TYPE_MEMBER_CHANGE_IN = 1;//进入房间事件。
    private static final int TYPE_MEMBER_CHANGE_OUT = 2;//退出房间事件。
    private static final int TYPE_MEMBER_CHANGE_HAS_CAMERA_VIDEO = 3;//有发摄像头视频事件。
    private static final int TYPE_MEMBER_CHANGE_NO_CAMERA_VIDEO = 4;//无发摄像头视频事件。
    private static final int TYPE_MEMBER_CHANGE_HAS_AUDIO = 5;//有发语音事件。
    private static final int TYPE_MEMBER_CHANGE_NO_AUDIO = 6;//无发语音事件。
    private static final int TYPE_MEMBER_CHANGE_HAS_SCREEN_VIDEO = 7;//有发屏幕视频事件。
    private static final int TYPE_MEMBER_CHANGE_NO_SCREEN_VIDEO = 8;//无发屏幕视频事件。


    public EnterLiveHelper(Context context, LiveActivity view) {
        mContext = context;
        mStepInOutView = view;
    }


    /**
     * 进入一个直播房间流程
     */
    public void startEnterRoom() {
        if (MySelfInfo.getInstance().isCreateRoom() == true) {
            createLive();
        } else {
            Log.i(TAG, "joinLiveRoom startEnterRoom ");
            joinLive(CurLiveInfo.getRoomNum());
        }

    }

    public void onDestory() {
        if (isInAVRoom) {
            quiteAVRoom();
        }
        mStepInOutView = null;
        mContext = null;
    }


    /**
     * 房间回调
     */
    private AVRoomMulti.EventListener mEventListener = new AVRoomMulti.EventListener() {
        // 进入房间成功回调
        @Override
        public void onEnterRoomComplete(int result) {
            if (result == 0) {
                Log.e(TAG, "enterAVRoom LogConstants.STATUS.SUCCEED room id" + MySelfInfo.getInstance().getMyRoomNum());
                //只有进入房间后才能初始化AvView
                QavsdkControl.getInstance().setAvRoomMulti(QavsdkControl.getInstance().getAVContext().getRoom());
                isInAVRoom = true;
                initAudioService();
                if (null != mStepInOutView) {
                    mStepInOutView.enterRoomComplete(MySelfInfo.getInstance().getIdStatus(), true);
                }
            } else {
                quiteAVRoom();
                Log.e(TAG, "enterAVRoom LogConstants.STATUS.FAILED result " + result);
            }

        }

        // 当前用户离开房间
        @Override
        public void onExitRoomComplete() {
            Log.e(TAG, "AVRoomMulti.EventListener:" + "onExitRoomComplete");

            isInAVRoom = false;
            quiteIMChatRoom();
            CurLiveInfo.setCurrentRequestCount(0);
            uninitAudioService();
            //通知结束
            if (mStepInOutView != null) {
                mStepInOutView.quiteRoomComplete(MySelfInfo.getInstance().getIdStatus(), true, null);
            }
        }

        // 当前用户的连接断了
        @Override
        public void onRoomDisconnect(int i) {
            Log.e(TAG, "AVRoomMulti.EventListener:" + "onRoomDisconnect");
            this.onExitRoomComplete();
        }

        // 当前用户所在房间成员变化
        @Override
        public void onEndpointsUpdateInfo(int eventid, String[] updateList) {
            Log.d(TAG, "onEndpointsUpdateInfo. eventid = " + eventid);

            switch (eventid) {
                case TYPE_MEMBER_CHANGE_IN:
                    // 有人进入房间， 自定义消息里 AVIMCMD_EnterLive 也代表有人进入房间（通过非主播进入房间的onExitRoomComplete进行调用）
                    Log.i(TAG, "stepin id  " + updateList.length);
                    if (null != mStepInOutView) {
                        mStepInOutView.memberJoinLive(updateList);
                    }
                    break;
                case TYPE_MEMBER_CHANGE_OUT:
                    // 有人离开房间， 自定义消息里 AVIMCMD_ExitLive 也代表有人离开房间（通过非主播进入房间的onExitRoomComplete进行调用）
                    if (null != mStepInOutView) {
                        Log.e(TAG, "AVRoomMulti.EventListener  id length  " + updateList.length);
                        mStepInOutView.memberQuiteLive(updateList);
                    }
                    break;
                case TYPE_MEMBER_CHANGE_HAS_CAMERA_VIDEO:
                    // 有人上麦， （自定义消息里 AVIMCMD_MUlTI_JOIN 也代表有人上麦，但是不处理视频相关逻辑。）
                    video_ids.clear();
                    for (String id : updateList) {
                        video_ids.add(id);
                        Log.i(TAG, "camera id " + id);
                    }
                    Intent intent = new Intent(Constants.ACTION_CAMERA_OPEN_IN_LIVE);
                    intent.putStringArrayListExtra("ids", video_ids);
                    mContext.sendBroadcast(intent);
                    break;
                case TYPE_MEMBER_CHANGE_NO_CAMERA_VIDEO: {
                    // 有人下麦， （自定义消息里 AVIMCMD_MULTI_CANCEL_INTERACT 也代表有人下麦，但是不处理视频相关逻辑。）
                    ArrayList<String> close_ids = new ArrayList<String>();
                    String ids = "";
                    for (String id : updateList) {
                        close_ids.add(id);
                        ids = ids + " " + id;

                    }
                    Log.e(TAG, "close camera callback" + "STATUS.SUCCEED close ids " + ids);

                    Intent closeintent = new Intent(Constants.ACTION_CAMERA_CLOSE_IN_LIVE);
                    closeintent.putStringArrayListExtra("ids", close_ids);
                    mContext.sendBroadcast(closeintent);
                    break;
                }
                case TYPE_MEMBER_CHANGE_HAS_SCREEN_VIDEO:
                    // 有人打开了屏幕分享
                    video_ids.clear();
                    for (String id : updateList) {
                        video_ids.add(id);
                        Log.i(TAG, "camera id " + id);
                    }
                    Intent intent2 = new Intent(Constants.ACTION_SCREEN_SHARE_IN_LIVE);
                    intent2.putStringArrayListExtra("ids", video_ids);
                    mContext.sendBroadcast(intent2);
                    break;
                case TYPE_MEMBER_CHANGE_NO_SCREEN_VIDEO: {
                    // 有人取消了屏幕分享
                    ArrayList<String> close_ids = new ArrayList<String>();
                    String ids = "";
                    for (String id : updateList) {
                        close_ids.add(id);
                        ids = ids + " " + id;

                    }
                    Log.e(TAG, "close camera callback LogConstants.STATUS.SUCCEED, close ids " + ids);

                    Intent closeintent = new Intent(Constants.ACTION_CAMERA_CLOSE_IN_LIVE);
                    closeintent.putStringArrayListExtra("ids", close_ids);
                    mContext.sendBroadcast(closeintent);
                    break;
                }
                case TYPE_MEMBER_CHANGE_HAS_AUDIO:
                    break;
                default:
                    break;
            }

        }

        @Override
        public void onPrivilegeDiffNotify(int i) {
            Log.e(TAG, "AVRoomMulti.EventListener:" + "onPrivilegeDiffNotify:" + i);
        }

        @Override
        public void onSemiAutoRecvCameraVideo(String[] strings) {
            Log.e(TAG, "AVRoomMulti.EventListener:" + "onSemiAutoRecvCameraVideo:" + strings);

            if (null != mStepInOutView) {
                mStepInOutView.alreadyInLive(strings);
            }
        }

        @Override
        public void onCameraSettingNotify(int i, int i1, int i2) {
            Log.e(TAG, "AVRoomMulti.EventListener:" + "onCameraSettingNotify:" + i + " --- " + i1 + "---  " + i2);
        }

        @Override
        public void onRoomEvent(int i, int i1, Object o) {
//            sdk事件通知。 用于通知从创建房间到退出时的一些事件，目前只通知连接某个接口机ip超时
            Log.e(TAG, "AVRoomMulti.EventListener:" + "onRoomEvent:" + i + " --- " + i1 + "---  " + o);
        }


    };


    /**
     * 1_5上传房间信息 。主播创建房间完成
     */
    public void notifyServerCreateRoom() {


    }

    /**
     * 1_1 创建一个直播
     */
    private void createLive() {
        createIMChatRoom();
    }

    /**
     * 2_1加入一个房间
     */
    private void joinLive(int roomNum) {
        joinIMChatRoom(roomNum);
    }


    /**
     * 1_2创建一个IM聊天室
     */
    private void createIMChatRoom() {
        final ArrayList<String> list = new ArrayList<String>();
        final String roomName = "liveroom";
        TIMGroupManager.getInstance().createGroup("AVChatRoom", list, roomName, "" + MySelfInfo.getInstance().getMyRoomNum(), new TIMValueCallBack<String>() {
            @Override
            public void onError(int i, String s) {
                Log.i(TAG, "onError " + i + "   " + s);
                //已在房间中,重复进入房间
                if (i == Constants.IS_ALREADY_IN_ROOM) {
                    isInChatRoom = true;
                    createAVRoom(MySelfInfo.getInstance().getMyRoomNum());
                    return;
                }
                // 创建IM房间失败，提示失败原因，并关闭等待对话框，退出av房间
                Log.e(TAG, "create live im group LogConstants.STATUS.FAILED code：" + i + " msg:" + s);
                Toast.makeText(mContext, "create IM room fail " + s + " " + i, Toast.LENGTH_SHORT).show();
                quiteAVRoom();

            }

            @Override
            public void onSuccess(String s) {
                Log.e(TAG, "create live im group LogConstants.STATUS.SUCCEED group id " + MySelfInfo.getInstance().getMyRoomNum());
                isInChatRoom = true;
                //创建AV房间
                createAVRoom(MySelfInfo.getInstance().getMyRoomNum());

            }
        });

    }

    /**
     * 2_2加入一个聊天室
     */
    private void joinIMChatRoom(final int chatRoomId) {
        Log.e(TAG, "join im chat room room id " + chatRoomId);

        TIMGroupManager.getInstance().applyJoinGroup("" + chatRoomId, Constants.APPLY_CHATROOM + chatRoomId, new TIMCallBack() {
            @Override
            public void onError(int i, String s) {
                //已经在是成员了
                if (i == Constants.IS_ALREADY_MEMBER) {
                    Log.i(TAG, "joinLiveRoom joinIMChatRoom callback succ ");
                    joinAVRoom(CurLiveInfo.getRoomNum());
                    isInChatRoom = true;
                } else {
                    Log.e(TAG, "join im chat room  LogConstants.STATUS.FAILED code:" + i + " msg:" + s);
                    if (mContext != null) {
                        Toast.makeText(mContext, "join IM room fail " + s + " " + i, Toast.LENGTH_SHORT).show();
                    }
                    quiteAVRoom();
                }
            }

            @Override
            public void onSuccess() {
                Log.e(TAG, "join im chat room onSuccess room id " + chatRoomId);
                isInChatRoom = true;
                joinAVRoom(CurLiveInfo.getRoomNum());
            }
        });

    }

    /**
     * 1_3创建一个AV房间
     */
    private void createAVRoom(int roomNum) {
        Log.e(TAG, "create av room room id " + MySelfInfo.getInstance().getMyRoomNum());
        EnterAVRoom(roomNum);
    }

    /**
     * 2_2加入一个AV房间
     */
    private void joinAVRoom(int avRoomNum) {
        Log.e(TAG, "join av room AV room id " + avRoomNum);
        EnterAVRoom(avRoomNum);
    }

    /**
     * 进入AV房间
     *
     * @param roomNum
     */
    private void EnterAVRoom(int roomNum) {
        Log.i(TAG, "createlive joinLiveRoom enterAVRoom " + roomNum);
        AVContext avContext = QavsdkControl.getInstance().getAVContext();
        byte[] authBuffer = null;//权限位加密串；TODO：请业务侧填上自己的加密串

        AVRoomMulti.EnterParam.Builder enterRoomParam = new AVRoomMulti.EnterParam.Builder(roomNum);
        if (MySelfInfo.getInstance().getIdStatus() == Constants.HOST) {
            // teacher
            enterRoomParam.auth(Constants.HOST_AUTH, authBuffer)
                    .avControlRole(Constants.HOST_ROLE)
                    .autoCreateRoom(true)
                    .isEnableMic(true)
                    .isEnableSpeaker(true)
                    .audioCategory(AVRoomMulti.AUDIO_CATEGORY_MEDIA_PLAY_AND_RECORD);
        } else if (MySelfInfo.getInstance().getIdStatus() == Constants.VIDEO_MEMBER) {
            // 上麦DJ 进入房间
            enterRoomParam.auth(Constants.VIDEO_MEMBER_AUTH, authBuffer)
                    .avControlRole(Constants.VIDEO_MEMBER_ROLE)
                    .autoCreateRoom(false)
                    .isEnableSpeaker(true)
                    .audioCategory(AVRoomMulti.AUDIO_CATEGORY_MEDIA_PLAY_AND_RECORD);
            Log.i(TAG, "上麦DJ 进入房" + roomNum);
        } else {
            // normal
            enterRoomParam.auth(Constants.NORMAL_MEMBER_AUTH, authBuffer)
                    .avControlRole(Constants.NORMAL_MEMBER_ROLE)
                    .autoCreateRoom(false)
                    .isEnableSpeaker(true)
                    .audioCategory(AVRoomMulti.AUDIO_CATEGORY_MEDIA_PLAYBACK);
        }
        enterRoomParam.videoRecvMode(AVRoomMulti.VIDEO_RECV_MODE_SEMI_AUTO_RECV_CAMERA_VIDEO);

        enterRoomParam.isDegreeFixed(true);
        enterRoomParam.isEnableHdAudio(true);
        if (avContext != null) {
            // create room
            int ret = avContext.enterRoom(mEventListener, enterRoomParam.build());
            Log.i(TAG, "EnterAVRoom " + ret);
        }

    }

    /**
     * 当前用户 在av房间时则退出当前所在AV房间，不在av房间则退出im房间并清空其他数据
     */
    public void quiteAVRoom() {
        Log.e(TAG, "quit av room ");

        if (isInAVRoom == true) {
            AVContext avContext = QavsdkControl.getInstance().getAVContext();
            if (null != avContext) {
                avContext.exitRoom();
            }
        } else {
            quiteIMChatRoom();
            CurLiveInfo.setCurrentRequestCount(0);
            uninitAudioService();
            //通知结束
            if (null != mStepInOutView) {
                mStepInOutView.quiteRoomComplete(MySelfInfo.getInstance().getIdStatus(), true, null);
            }
        }
    }

    /**
     * 退出IM房间
     */
    private void quiteIMChatRoom() {
        if ((isInChatRoom == true)) {
            if (MySelfInfo.getInstance().getIdStatus() == Constants.HOST) {
                //主播解散群
                TIMGroupManager.getInstance().deleteGroup("" + CurLiveInfo.getRoomNum(), new TIMCallBack() {
                    @Override
                    public void onError(int i, String s) {
                        Log.e(TAG, "delete im room  LogConstants.STATUS.FAILED code:" + i + " msg:" + s);
                    }

                    @Override
                    public void onSuccess() {
                        Log.e(TAG, "delete im room LogConstants.STATUS.SUCCEED room id " + CurLiveInfo.getRoomNum());
                        isInChatRoom = false;
                    }
                });
                TIMManager.getInstance().deleteConversation(TIMConversationType.Group, "" + MySelfInfo.getInstance().getMyRoomNum());
            } else {
                //成员退出群
                TIMGroupManager.getInstance().quitGroup("" + CurLiveInfo.getRoomNum(), new TIMCallBack() {
                    @Override
                    public void onError(int i, String s) {
                        Log.e(TAG, "quite im room  LogConstants.STATUS.FAILED code:" + i + " msg:" + s);
                    }

                    @Override
                    public void onSuccess() {
                        Log.e(TAG, "quite im room  LogConstants.STATUS.SUCCEED room id " + CurLiveInfo.getRoomNum());
                        isInChatRoom = false;
                    }
                });
            }

            //
        }
    }


    public void initAvUILayer(View avView) {
        //初始化AVSurfaceView
        if (QavsdkControl.getInstance().getAVContext() != null) {
            QavsdkControl.getInstance().initAvUILayer(mContext.getApplicationContext(), avView);
        }
    }

    private void initAudioService() {
        if ((QavsdkControl.getInstance() != null) && (QavsdkControl.getInstance().getAVContext() != null) && (QavsdkControl.getInstance().getAVContext().getAudioCtrl() != null)) {
            QavsdkControl.getInstance().getAVContext().getAudioCtrl().startTRAEService();
        }
    }

    private void uninitAudioService() {
        if ((QavsdkControl.getInstance() != null) && (QavsdkControl.getInstance().getAVContext() != null) && (QavsdkControl.getInstance().getAVContext().getAudioCtrl() != null)) {
            QavsdkControl.getInstance().getAVContext().getAudioCtrl().stopTRAEService();
        }
    }

}
